﻿namespace StockSharp.AlfaDirect
{
	using System;

	using Ecng.Collections;

	using StockSharp.BusinessEntities;

	/// <summary>
	/// Вспомагательный класс, который используется для доступа к специфичной AlfaDirect информации через <see cref="IExtendableEntity.ExtensionInfo"/>.
	/// </summary>
	public static class AlfaExtensions
	{
		private const string _securityKeyCurrency = "key_currency";
		private const string _securityKeyPaperNo = "paper_no";
		private const string _securityKeyPlaceCode = "place_code";
		private const string _securityKeyOpenInteres = "open_pos_qty";
		private const string _orderAveragePrice = "avg_trd_price";

		/// <summary>
		/// Получить валюту для инструмента.
		/// </summary>
		/// <param name="security">Инструмент.</param>
		/// <returns>Валюта.</returns>
		public static string GetCurrency(this Security security)
		{
			return security.GetValue<string>(_securityKeyCurrency);
		}

		internal static void SetCurrency(this Security security, string currency)
		{
			security.AddValue(_securityKeyCurrency, currency);
		}

		/// <summary>
		/// Получить значение открытого интереса по инструменту.
		/// </summary>
		/// <param name="security">Инструмент.</param>
		/// <returns>Значение открытого интереса.</returns>
		public static long GetOpenInteres(this Security security)
		{
			return security.GetValue<long>(_securityKeyOpenInteres);
		}

		internal static void SetOpenInteres(this Security security, long openInteres)
		{
			security.AddValue(_securityKeyOpenInteres, openInteres);
		}

		/// <summary>
		/// Получить AlfaDirect-номер инструмента.
		/// </summary>
		/// <param name="security">Инструмент.</param>
		/// <returns>AlfaDirect-номер инструмента.</returns>
		public static string GetPaperNo(this Security security)
		{
			return security.GetValue<string>(_securityKeyPaperNo);
		}

		internal static void SetPaperNo(this Security security, string paperNo)
		{
			security.AddValue(_securityKeyPaperNo, paperNo);
		}

		/// <summary>
		/// Получить код площадки инструмента.
		/// </summary>
		/// <param name="security">Инструмент.</param>
		/// <returns>Код площадки.</returns>
		public static string GetPlaceCode(this Security security)
		{
			return security.GetValue<string>(_securityKeyPlaceCode);
		}

		internal static void SetPlaceCode(this Security security, string placeCode)
		{
			security.AddValue(_securityKeyPlaceCode, placeCode);
		}

		/// <summary>
		/// Получить среднюю цену исполнения.
		/// </summary>
		/// <param name="order">Заявка.</param>
		/// <returns>Средняя цену исполнения..</returns>
		public static decimal GetAlfaAveragePrice(this Order order)
		{
			return order.GetValue<decimal>(_orderAveragePrice);
		}

		internal static void SetAlfaAveragePrice(this Order order, decimal price)
		{
			order.AddValue(_orderAveragePrice, price);
		}

		private static void AddValue(this IExtendableEntity entity, string key, object value)
		{
			if (entity == null)
				throw new ArgumentNullException("entity");

			if (entity.ExtensionInfo == null)
				throw new ArgumentException("entity");

			entity.ExtensionInfo[key] = value;
		}

		private static T GetValue<T>(this IExtendableEntity entity, string key)
		{
			if (entity == null)
				throw new ArgumentNullException("entity");

			if (entity.ExtensionInfo == null)
				throw new ArgumentException("entity");

			return (T)entity.ExtensionInfo.TryGetValue(key);
		}

		internal static void RaisePropertyChanged(this IExtendableEntity entity)
		{
			if (entity == null)
				throw new ArgumentNullException("entity");

			entity.NotifyPropertyChanged("ExtensionInfo");
		}
	}
}